home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / RISCy Bitsness / cpu2 / cpu2.v < prev    next >
Encoding:
Verilog source code  |  1992-06-19  |  10.7 KB  |  545 lines  |  [TEXT/MPS ]

  1. /*
  2. 10     29        28-24    23-19 13-0
  3. 00    0/1 l/s     rs        ra      abs - sext
  4.  
  5.     load        rs, n(ra)
  6.     store        rs, n(ra)
  7.  
  8. 10     29,18-15    28-24    23-19     14-0/4-0
  9. 01      type        rd        rs         v/r (sext)
  10.  
  11.     add        rd, rs, r/v        0
  12.     sub     rd, rs, r/v        1
  13.     and        rd, rs, r/v        2
  14.     or        rd, rs, r/v        3
  15.     xor        rd, rs, r/v        4
  16.     lt        rd, rs, r/v        5
  17.     le        rd, rs, r/v        6
  18.     eq        rd, rs, r/v        7
  19.     lsh        rd, rs, r/v        8
  20.     jmp        rd, rs, r/v        9
  21.  
  22. 10     29             28-24    23-0
  23. 10    0/1 t/f      r        abs
  24.         
  25.     bt        r, abs
  26.     bf        r, abs
  27.  
  28. 10     29             28-24    23-0/15-0
  29. 11    0/1 /h      r        v
  30.  
  31.     const    r, v        23-0
  32.     consth    r, v        15-0
  33.  
  34.  
  35.  
  36. bus:
  37.     clock
  38.     reset
  39.     a31_2
  40.     d31_0
  41.     r/w
  42.     start
  43.     ack
  44.     near
  45. */
  46.     
  47. module cpu2(clock, reset, a, d, rw, start, ack);
  48.  
  49.     input            clock;
  50.     input            reset;
  51.     
  52.     inout     [31: 0]d;
  53.     reg         [31: 0]dd;
  54.     assign        d = dd;
  55.     
  56.     output     [31: 0]a;
  57.     reg         [31: 0]a;
  58.     
  59.     output            rw;
  60.     reg                rw;
  61.     
  62.     output            start;
  63.     reg                start;
  64.     
  65.     output            near;
  66.     reg                near;
  67.     
  68.     input            ack;
  69.     
  70.     wire     [31: 0]ins_cache_in,
  71.                     write_data_out,
  72.                     write_addr_out,
  73.                     write_buffer_data,
  74.                     data_cache_in,
  75.                     s1,
  76.                     s2,
  77.                     s2a,
  78.                     exec_s1_data,
  79.                     exec_s2_data,
  80.                     dest;
  81.     
  82.     wire            ins_cache_valid,
  83.                     data_cache_valid,
  84.                     write_buffer_full,
  85.                     write_buffer_ready,
  86.                     write_buffer_hit,
  87.                     do_branch,
  88.                     reg_stall;
  89.                     
  90.     reg                load_ins_cache,
  91.                     load_data_cache,
  92.                     write_buffer_write,
  93.                     exec_br,
  94.                     exec_bcond,
  95.                     exec_btest,
  96.                     ins_valid,
  97.                     exec_const,
  98.                     next_const,
  99.                     next_br,
  100.                     next_bcond,
  101.                     next_btest,
  102.                     next_lda,
  103.                     next_ls,
  104.                     next_st,
  105.                     exec_lda,
  106.                     exec_ls,
  107.                     exec_st,
  108.                     ls_busy,
  109.                     ls_start,
  110.                     ls_st,
  111.                     mem_busy,
  112.                     mem_read_ok,
  113.                     mem_write_ok,
  114.                     pc_read,
  115.                     pc_read_ok,
  116.                     mem_read,
  117.                     mem_write,
  118.                     next_stall,
  119.                     write_done;
  120.     
  121.     reg         [31: 0]pc_addr,
  122.                     write_addr,
  123.                     write_ram_addr,
  124.                     pc,
  125.                     i,
  126.                     load_buff,
  127.                     write_buff,
  128.                     write_data_buff,
  129.                     exec_const_val,
  130.                     next_const_val,
  131.                     d_in;
  132.                     
  133.     reg         [ 4: 0]exec_op,
  134.                     next_op,
  135.                     next_s1,
  136.                     next_s2,
  137.                     next_d,
  138.                     next_s1_addr,
  139.                     next_s2_addr,
  140.                     exec_s1_addr,
  141.                     exec_s2_addr,
  142.                     load_addr;
  143.  
  144.     assign            data_cache_in = (data_cache_valid?write_buffer_data:d);
  145.     
  146.     cache            ins_cache(reset, pc_addr, ins_cache_in, ins_cache_valid, d_in, load_ins_cache);
  147.     cache            data_cache(reset, write_ram_addr, data_cache_in, data_cache_valid, data_cache_in, load_data_cache);
  148.     write_buffer    wb(reset, clock, write_ram_addr, write_data_buff, write_buffer_write, write_buffer_data, write_done, write_buffer_hit, write_buffer_full, write_buffer_ready, write_data_out, write_addr_out);
  149.  
  150. //
  151. //    reset
  152. //
  153.     
  154.         always @(negedge clock) 
  155.         if (~reset)
  156.         begin
  157.             start = 1;
  158.             load_ins_cache = 0;
  159.             load_data_cache = 0;
  160.             write_buffer_write = 0;
  161.             exec_br = 0;
  162.             exec_bcond = 0;
  163.             exec_btest = 0;
  164.             ins_valid = 0;
  165.             exec_const = 0;
  166.             next_const = 0;
  167.             next_br = 0;
  168.             next_bcond = 0;
  169.             next_btest = 0;
  170.             next_lda = 0;
  171.             next_ls = 0;
  172.             next_st = 0;
  173.             exec_lda = 0;
  174.             exec_ls = 0;
  175.             exec_st = 0;
  176.             ls_busy = 0;
  177.             ls_start = 0;
  178.             ls_st = 0;
  179.             pc_addr = 0;
  180.             write_addr = 0;
  181.             write_ram_addr = 0;
  182.             i = 0;
  183.             load_buff = 0;
  184.             write_buff = 0;
  185.             write_data_buff = 0;
  186.             exec_const_val = 0;
  187.             next_const_val = 0;
  188.             write_done = 0;
  189.             exec_op = 0;
  190.             next_op = 0;
  191.             next_s1 = 0;
  192.             next_s2 = 0;
  193.             next_d = 0;
  194.             next_s1_addr = 0;
  195.             next_s2_addr = 0;
  196.             exec_s1_addr = 0;
  197.             exec_s2_addr = 0;
  198.             load_addr = 0;
  199.             mem_busy = 0;
  200.             pc_read = 0;
  201.             mem_read = 0;
  202.             mem_write = 0;
  203.             pc_read_ok = 0;
  204.             mem_read_ok = 0;
  205.             mem_write_ok = 0;
  206.             next_stall = 1;
  207.             pc = 0;
  208.             near = 0;
  209.         end
  210.  
  211.  
  212. //
  213. //    fetch
  214. //
  215.  
  216. //    initial $gr_waves("load_ins_cache", load_ins_cache,
  217. //                      "ins_valid", ins_valid,
  218. //                      "ins_cache_valid", ins_cache_valid,
  219. //                      "mem_start",mem_start,
  220. //                      "mem_busy",mem_busy,
  221. //                      "mem_read",mem_read,
  222. //                      "mem_write",mem_write,
  223. //                      "write_buffer_write", write_buffer_write,
  224. //                      "write_buffer_ready", write_buffer_ready,
  225. //                      "pc_addr",pc_addr);
  226.     always @(negedge clock) 
  227.     if (reset) begin
  228.         load_ins_cache = 0;
  229.         #1
  230.         if (~ins_valid) begin
  231.             pc_addr = pc;
  232.             pc = pc+4;
  233.             @(posedge clock);
  234.             if (ins_cache_valid) begin
  235.                 i = ins_cache_in;
  236.             end else begin
  237.                 pc_read = 1;
  238.                 @(negedge clock);
  239.                 while (!pc_read_ok)    // wait for any pending cycles to complete
  240.                     @(negedge clock);
  241.                 @(posedge clock);
  242.                 pc_read = 0;
  243.                 while (mem_busy)                            // wait for it to complete
  244.                     @(posedge clock);
  245.                 load_ins_cache = 1;
  246.                 i = d_in;
  247.             end 
  248.             #1;
  249.             ins_valid = 1; 
  250.         end
  251.     end
  252.  
  253.  
  254. //
  255. //    decode
  256. //
  257.  
  258.     assign reg_stall = ls_busy && (load_addr == next_s1 || load_addr == next_s2);
  259.  
  260. /*    initial $gr_waves("ins_valid", ins_valid,
  261.                       "ins_cache_valid", ins_cache_valid,
  262.                       "reg_stall", reg_stall,
  263.                       "next_op", next_op,
  264.                       "next_const", next_const,
  265.                       "next_br", next_br,
  266.                       "next_bcond",next_bcond,
  267.                       "next_btest",next_btest,
  268.                       "next_s1",next_s1,
  269.                       "next_s2",next_s2,
  270.                       "next_d",next_d,
  271.                       "next_lda",next_lda,
  272.                       "next_ls",next_ls,
  273.                       "next_st",next_st,
  274.                       "next_const_val",next_const_val);
  275. */
  276.     always @(negedge clock) 
  277.     if (reset) 
  278.     if (~reg_stall && ins_valid) begin
  279.         ins_valid = 0;
  280.         case (i[31:30])
  281.         0:    begin
  282.                 next_op     = 0;
  283.                 next_const     = 1;
  284.                 next_br     = 0;
  285.                 next_bcond     = 0;
  286.                 next_btest     = 0;
  287.                 next_s1     = i[28:24];
  288.                 next_s2     = (i[29] ? i[23:19] : 0);
  289.                 next_d      = 0;
  290.                 next_lda      = (i[29] ? 0 : i[23:19]);
  291.                 next_ls     = 1;
  292.                 next_st     = i[29];
  293.                 next_const_val = {i[18],i[18],i[18],i[18],i[18],i[18],i[18],i[18],
  294.                                   i[18],i[18],i[18],i[18],i[18],i[18],
  295.                                   i[17:0]};
  296.                 #1;
  297.                 next_stall = ls_busy;
  298.             end
  299.         1:    begin
  300.                 next_op     = i[18:15];
  301.                 next_const     = i[29];
  302.                 next_br     = i[18:15] == 9;
  303.                 next_bcond     = 0;
  304.                 next_btest     = 0;
  305.                 next_s1     = i[23:19];
  306.                 next_s2     = (i[29] ? 0 : i[4:0]);
  307.                 next_d      = i[28:24];
  308.                 next_ls     = 0;
  309.                 next_st     = 0;
  310.                 next_const_val = {i[13],i[13],i[13],i[13],i[13],i[13],i[13],i[13],
  311.                                   i[13],i[13],i[13],i[13],i[13],i[13],i[13],i[13],
  312.                                   i[13],i[13],i[12:0]};
  313.                 #1;
  314.                 next_stall = reg_stall;
  315.             end
  316.         2:    begin
  317.                 next_op     = 17;
  318.                 next_const     = 1;
  319.                 next_br     = 1;
  320.                 next_bcond     = 1;
  321.                 next_btest     = i[29];
  322.                 next_s1     = i[28:24];
  323.                 next_s2     = 0;
  324.                 next_d      = 0;
  325.                 next_ls     = 0;
  326.                 next_st     = 0;
  327.                 next_const_val = {8'b0,i[23:0]};
  328.                 #1;
  329.                 next_stall     = reg_stall;
  330.             end
  331.         3:    begin
  332.                 next_op     = (i[29]?18:17);
  333.                 next_const     = 1;
  334.                 next_br     = 0;
  335.                 next_bcond     = 0;
  336.                 next_btest     = 0;
  337.                 next_s1     = (i[29]?i[28:24]:0);
  338.                 next_s2     = 0;
  339.                 next_d      = i[28:24];
  340.                 next_ls     = 0;
  341.                 next_st     = 0;
  342.                 next_const_val= {8'b0,i[23:0]};
  343.                 #1;
  344.                 next_stall     = reg_stall;
  345.             end
  346.                 
  347.         endcase
  348.     end else begin
  349.         #1
  350.         next_stall = 1;
  351.     end
  352.     
  353. //
  354. //    execute
  355. //
  356.  
  357.     assign    s1 = (exec_s1_addr == 0 ? 0: 
  358.                   exec_s1_addr == write_addr ? write_buff : 
  359.                   exec_s1_addr == load_addr  ? load_buff  : exec_s1_data);
  360.                   
  361.     assign    s2a =(exec_s2_addr == 0             ? 0 :
  362.                   exec_s2_addr == write_addr ? write_buff : 
  363.                   exec_s2_addr == load_addr  ? load_buff  : exec_s2_data);
  364.                   
  365.     assign    s2 = (exec_const ?exec_const_val : s2a);
  366.     
  367.     regfile        rf(clock, write_addr, write_buff, exec_s1_addr, exec_s1_data, exec_s2_addr, exec_s2_data);
  368.     
  369.     alu            aa(exec_op, dest, s1, s2);
  370.     
  371.     assign    do_branch = exec_br && (!exec_bcond || exec_btest^dest[31]);
  372.  
  373. /*    initial $gr_waves("exec_op", exec_op,
  374.                       "exec_const", exec_const,
  375.                       "exec_br", exec_br,
  376.                       "exec_bcond",exec_bcond,
  377.                       "exec_btest",exec_btest,
  378.                       "exec_s1_addr",exec_s1_addr,
  379.                       "exec_s2_addr",exec_s2_addr,
  380.                       "write_addr",write_addr,
  381.                       "exec_lda",exec_lda,
  382.                       "exec_ls",exec_ls,
  383.                       "exec_st",exec_st,
  384.                       "exec_const_val",exec_const_val,
  385.                       "reg_stall",reg_stall);
  386.  */
  387.     always @(negedge clock) 
  388.     if (reset) 
  389.     if (next_stall) begin
  390.         @(posedge clock)
  391.         write_addr = 0;
  392.     end else begin
  393.         exec_op = next_op;
  394.         exec_s1_addr = next_s1;
  395.         exec_s2_addr = next_s2;
  396.         exec_const_val = next_const_val;
  397.         exec_const = next_const;
  398.         exec_ls = next_ls;
  399.         exec_st = next_st;
  400.         exec_lda = next_lda;
  401.         exec_br = next_br;
  402.         exec_bcond = next_bcond;
  403.         exec_btest = next_btest;
  404.         
  405.         @(posedge clock);
  406.         
  407.         if (do_branch) begin
  408.             write_addr = next_d;
  409.             write_buff = pc;
  410.             #3
  411.             pc = dest;
  412.         end else
  413.         if (exec_ls) begin
  414.             write_addr = load_addr;
  415.             write_data_buff = s2a;
  416.             write_ram_addr = dest;
  417.             write_buff = load_buff;
  418.             load_addr = exec_lda;
  419.             ls_busy = 1;
  420.             ls_start = 1;
  421.             ls_st = exec_st;
  422.         end else begin
  423.             write_addr = next_d;
  424.             write_buff = dest;
  425.         end
  426.     end
  427. //
  428. //    write-back
  429. //
  430.     always @(negedge clock) 
  431.     if (reset) 
  432.     begin
  433.         if (write_addr == load_addr)
  434.             load_addr = 0;
  435.     end
  436.  
  437. //
  438. //    LS machine
  439. //
  440.  
  441. initial $gr_waves("write_buffer_full", write_buffer_full,
  442.                 "write_buffer_ready",write_buffer_ready,
  443.                 "write_ram_addr",write_ram_addr,
  444.                 "data_cache_valid",data_cache_valid,
  445.                 "exec_op",exec_op,
  446.                 "dest",dest,
  447.                 "s1",s1,
  448.                 "s2",s2);
  449.  
  450.     always @(negedge clock)  
  451.     if (reset) begin
  452.         load_data_cache = 0;
  453.         if (ls_start) begin
  454.             ls_start = 0;
  455.             if (ls_st) begin
  456.                 while (write_buffer_full) begin
  457.                     @(negedge clock);
  458.                 end
  459.                 if (data_cache_valid) 
  460.                     load_data_cache = 1;
  461.                 write_buffer_write = 1;
  462.                 @(posedge clock);
  463.                 write_buffer_write = 0;
  464.                 load_data_cache = 0;
  465.             end else begin
  466.                 @(posedge clock);
  467.                 if (data_cache_valid) begin
  468.                     load_buff = data_cache_in;
  469.                 end else 
  470.                 if (write_buffer_hit) begin
  471.                     load_buff = write_buffer_data;
  472.                 end else begin
  473.                     mem_read = 1;                // request memory
  474.                     @(negedge clock);
  475.                     while (!mem_read_ok)        // wait for any pending cycles to complete
  476.                         @(negedge clock);
  477.                     @(posedge clock);
  478.                     mem_read = 0;
  479.                     while (mem_busy)            // wait for it to complete
  480.                         @(posedge clock);
  481.                     load_data_cache = 1;
  482.                     load_buff = d_in;
  483.                 end
  484.             end
  485.             ls_busy = 0;
  486.         end
  487.     end
  488. //
  489. //    write buffer requests to ram
  490. //
  491.     always @(negedge clock)  
  492.     if (reset) begin 
  493.         write_done = 0;
  494.         if (write_buffer_ready) begin
  495.             mem_write = 1;
  496.             @(negedge clock);
  497.             while (!mem_write_ok)                // wait for any pending cycles to complete
  498.                 @(negedge clock);
  499.             @(posedge clock);
  500.             mem_write = 0;
  501.             while (mem_busy)                    // wait for it to complete
  502.                 @(posedge clock);
  503.             write_done = 1;
  504.         end
  505.     end
  506.         
  507.  
  508. //
  509. //    memory controller
  510. //
  511.     always @(posedge clock)  
  512.     if (reset) 
  513.     if (mem_read || mem_write || pc_read) begin
  514.         mem_busy = 1;
  515.         if (mem_read) begin
  516.             a = write_ram_addr;
  517.             dd = 32'bz;
  518.             rw = 1;
  519.             mem_read_ok = 1;
  520.         end else
  521.         if (mem_write) begin
  522.             a = write_addr_out;
  523.             dd = write_data_out;
  524.             rw = 0;
  525.             mem_write_ok = 1;
  526.         end else begin
  527.             a = pc_addr;
  528.             dd = 32'bz;
  529.             rw = 1;
  530.             pc_read_ok = 1;
  531.         end
  532.         start = 0;
  533.         @(negedge clock);
  534.         while (ack)
  535.             @(negedge clock);
  536.         d_in = d;
  537.         mem_read_ok = 0;
  538.         mem_write_ok = 0;
  539.         pc_read_ok = 0;
  540.         mem_busy = 0;
  541.         start = 1;
  542.     end
  543.  
  544. endmodule
  545.